import * as echarts from 'echarts/core'
import { ElMessage } from 'element-plus'
import { curveAPI } from '@/services/api'
import dayjs from 'dayjs'

export class ChartManager {
  static generateOption(curveData) {
    if (!curveData || !curveData.channels) {
      console.error('Invalid curve data:', curveData)
      return null
    }

    const positions = new Set()
    const unitsByPosition = new Map()

    // 收集位置和单位信息
    Object.entries(curveData.channels).forEach(([channel, channelData]) => {
      const position = channelData.config.position || '1'
      const unit = channelData.config.unit || ''
      positions.add(position)
      
      if (!unitsByPosition.has(position)) {
        unitsByPosition.set(position, new Set())
      }
      unitsByPosition.get(position).add(unit)
    })

    // 计算布局
    const positionArray = Array.from(positions).sort()
    const paddingTop = 5
    const totalHeight = 85
    const gridHeight = totalHeight / positionArray.length

    // 构建 dataset
    const datasets = positionArray.map((position, index) => {
      const channelsInPosition = Object.entries(curveData.channels)
        .filter(([_, data]) => (data.config.position || '1') === position)
      
      // 构建维度数组
      const dimensions = ['timestamp', ...channelsInPosition.map(([channel]) => channel)]
      
      // 构建数据源
      const timestamps = channelsInPosition[0][1].data.timestamps
      const source = timestamps.map((timestamp, i) => {
        const row = [timestamp * 1000]
        channelsInPosition.forEach(([_, data]) => {
          row.push(data.data.values[i])
        })
        return row
      })

      return {
        id: `dataset_${index}`,
        dimensions,
        source
      }
    })

    // 构建网格配置
    const grids = positionArray.map((_, index) => ({
      height: `${gridHeight}%`,
      top: `${paddingTop + index * gridHeight}%`,  // 添加顶部padding
      left: '100',
      right: '100',
      show: true,           // 显示网格
      borderWidth: 2,       // 边框宽度
      borderColor: '#000',  // 边框颜色
      z: 99                 // 确保边框在最上层
    }))

    // 构建X轴
    const xAxes = positionArray.map((_, index) => ({
      type: 'time',
      scale: true,
      gridIndex: index,
      show: index === positionArray.length - 1,
      axisLabel: {
        fontSize: 12,
        fontWeight: 'bold',
        formatter: value => dayjs(value).format('YY-MM-DD HH:mm:ss'),
        rotate: 15,
        align: 'right'
      },
      axisTick: {
        show: true,
        alignWithLabel: true,
        inside: true  // 刻度线朝上
      },
      axisLine: {
        onZero: false,
        show: true,
        lineStyle: {
          color: '#333'
        }
      },
      splitLine: {
        show: false
      }
    }))

    // 构建Y轴
    const yAxes = []
    let yAxisIndex = 0  // 添加 yAxisIndex 计数器
    const yAxisIndices = new Map()  // 用于存储每个位置的 Y 轴索引范围

    positionArray.forEach((position, positionIndex) => {
      const channelsInPosition = Object.entries(curveData.channels)
        .filter(([_, data]) => (data.config.position || '1') === position)

      // 按单位分组通道
      const channelsByUnit = new Map()
      channelsInPosition.forEach(([channel, data]) => {
        const unit = data.config.unit || ''
        if (!channelsByUnit.has(unit)) {
          channelsByUnit.set(unit, [])
        }
        channelsByUnit.get(unit).push([channel, data])
      })

      // 记录这个位置的起始 Y 轴索引
      const startYAxisIndex = yAxisIndex

      // 为每个单位创建一个Y轴
      Array.from(channelsByUnit.entries()).forEach(([unit, channels], unitIndex) => {
        yAxes.push({
          type: 'value',
          scale: true,
          gridIndex: positionIndex,
          position: unitIndex % 2 === 0 ? 'left' : 'right',
          name: unit,
          nameLocation: 'middle',
          nameGap: 40,
          nameTextStyle: {
            fontSize: 12,
            fontWeight: 'bold'
          },
          axisLine: {onZero: false, lineStyle: {width: 2 }},
          axisTick: { alignWithLabel: true, inside: true },
          axisLabel: {
            fontSize: 12,
            fontWeight: 'bold'
          }
        })
        yAxisIndex++
      })

      // 存储这个位置的 Y 轴索引范围
      yAxisIndices.set(position, {
        start: startYAxisIndex,
        count: yAxisIndex - startYAxisIndex
      })
    })

    // 构建系列
    const series = []
    positionArray.forEach((position, positionIndex) => {
      const channelsInPosition = Object.entries(curveData.channels)
        .filter(([_, data]) => (data.config.position || '1') === position)

      const channelsByUnit = new Map()
      channelsInPosition.forEach(([channel, data]) => {
        const unit = data.config.unit || ''
        if (!channelsByUnit.has(unit)) {
          channelsByUnit.set(unit, [])
        }
        channelsByUnit.get(unit).push([channel, data])
      })

      // 获取该位置的 Y 轴起始索引
      const yAxisInfo = yAxisIndices.get(position)
      let currentYAxisIndex = yAxisInfo.start

      // 为每个单位的通道分配对应的Y轴
      Array.from(channelsByUnit.entries()).forEach(([unit, channels]) => {
        channels.forEach(([channel, channelData]) => {
          series.push({
            name: channel,
            type: 'line',
            datasetIndex: positionIndex,
            encode: {
              x: 'timestamp',
              y: channel
            },
            xAxisIndex: positionIndex,
            yAxisIndex: currentYAxisIndex,  // 使用正确的 Y 轴索引
            showSymbol: false,
            color: channelData.config.color,
            smooth: false,
            lineStyle: {
              width: 1.5
            },
            animation: false
          })
        })
        currentYAxisIndex++  // 移动到下一个 Y 轴索引
      })
    })

    // 构建图例
    const legends = positionArray.map((_, positionIndex) => ({
      data: series
        .filter(s => s.xAxisIndex === positionIndex)
        .map(s => s.name),
      top: `${paddingTop + positionIndex * gridHeight + 2}%`,
      right: 120,
      orient: 'vertical',
      textStyle: {
        fontSize: 12,
        fontWeight: 'bold'
      }
    }))

    return {
      backgroundColor: '#ffffff',
      dataset: datasets,
      tooltip: {
        trigger: 'axis',  // 坐标轴触发
        axisPointer: {
          type: 'cross',  // 十字准星指示器
          label: {
            backgroundColor: '#6a7985'
          }
        },
        formatter: function(params) {
          if (params.length === 0) return '';
          
          const time = dayjs(params[0].value[0]).format('YYYY-MM-DD HH:mm:ss');
          let result = `${time}<br/>`;
          
          params.forEach(param => {
            result += `${param.seriesName}: ${param.value[param.dimensionNames[1]]}<br/>`;
          });
          
          return result;
        }
      },
      grid: grids,
      xAxis: xAxes,
      yAxis: yAxes,
      series: series,
      legend: legends,
      animation: false
    }
  }

  static generateDatasetOption(curveData) {
    try {
      if (!curveData?.channels) {
        return [{ dimensions: ['timestamp'], source: [] }]  // 返回空数据集
      }

      const channelEntries = Object.entries(curveData.channels)
      const positions = new Set()
      
      // 收集位置信息
      channelEntries.forEach(([_, channelData]) => {
        if (channelData?.config) {
          const position = channelData.config.position || '1'
          positions.add(position)
        }
      })

      if (positions.size === 0) {
        positions.add('1')
      }

      const positionArray = Array.from(positions).sort()
      const datasets = positionArray.map((position, index) => {
        const channelsInPosition = channelEntries.filter(([_, data]) => 
          (data?.config?.position || '1') === position
        )

        // 构建维度数组
        const dimensions = ['timestamp', ...channelsInPosition.map(([channel]) => channel)]

        // 获取第一个有效通道的时间戳
        const firstValidChannel = channelsInPosition.find(([_, data]) => 
          data?.data?.timestamps?.length > 0
        )

        // 如果没有有效数据，返回空数据集
        if (!firstValidChannel) {
          return {
            id: `dataset_${index}`,
            dimensions,
            source: []
          }
        }

        const timestamps = firstValidChannel[1].data.timestamps
        const source = timestamps.map((timestamp, i) => {
          const row = [timestamp * 1000]
          channelsInPosition.forEach(([_, data]) => {
            row.push(data?.data?.values?.[i] ?? null)
          })
          return row
        })

        return {
          id: `dataset_${index}`,
          dimensions,
          source
        }
      })

      return datasets

    } catch (error) {
      console.error('Error in generateDatasetOption:', error)
      return [{ dimensions: ['timestamp'], source: [] }]  // 错误时返回空数据集
    }
  }
}


export class ChartGesture {
  constructor(chartInstance, curveData, settings) {
    this.myChart = chartInstance
    this.curveData = curveData
    this.settings = settings
    
    // 初始化状态
    this.isDragging = false
    this.startX = 0
    this.startY = 0
    this.redBox = null
    this.crosshair = null
    this.tooltip = null
    this.isDisplayCross = true
    
    // 保存原始数据和选项
    this.originalOption = this.myChart.getOption()
    
    // 初始化
    this.zr = this.myChart.getZr()
    this.bindEvents()
    
    // 添加节流相关的属性
    this.lastDrawTime = 0
    this.throttleDelay = 20  // 20ms 的节流延迟
  }

  // 添加节流函数
  throttle(func, delay) {
    const now = Date.now()
    if (now - this.lastDrawTime >= delay) {
      func()
      this.lastDrawTime = now
    }
  }

  drawRedBox(event) {
    const { offsetX, offsetY } = event
    this.throttle(() => {
      if (this.redBox) {
        this.zr.remove(this.redBox)
      }
      this.redBox = new echarts.graphic.Rect({
        shape: {
          x: Math.min(this.startX, offsetX),
          y: Math.min(this.startY, offsetY),
          width: Math.abs(offsetX - this.startX),
          height: Math.abs(offsetY - this.startY)
        },
        style: {
          fill: 'none',
          stroke: 'red',
          lineWidth: 3
        },
        z: 998
      })
      this.zr.add(this.redBox)
    }, this.throttleDelay)
  }

  handleMouseDown(event) {
    this.startX = event.offsetX
    this.startY = event.offsetY
    this.isDragging = true
  }

  handleMouseMove(event) {
    if (this.isDragging) {
      this.drawRedBox(event)
    }
  }

  handleMouseUp(event) {
    this.isDragging = false
    const deltaX = event.offsetX - this.startX

    if (deltaX > 5) {
      // 从左向右拖动 - 放大
      const xStart = this.myChart.convertFromPixel({ xAxisIndex: 0 }, this.startX)
      const xEnd = this.myChart.convertFromPixel({ xAxisIndex: 0 }, event.offsetX)
      this.zoomToRange(xStart, xEnd)
    } else if (deltaX < -5) {
      // 从右向左拖动 - 重置
      this.resetZoom()
    }

    if (this.redBox) {
      this.zr.remove(this.redBox)
      this.redBox = null
    }
  }

  async zoomToRange(start, end) {
    try {
      const response = await curveAPI.getCurveData({
        experimentId: this.settings.experimentId,
        channels: this.settings.channels,
        timeRange: {
          start: start/1000.0,
          end: end/1000.0
        }
      })
      
      if (!response?.data?.data?.channels) {
        console.error('Invalid response structure:', response)
        throw new Error('返回数据结构不正确')
      }
      // 只更新数据集
      const datasets = ChartManager.generateDatasetOption(response.data.data)
      if (!datasets) {
        throw new Error('数据集生成失败')
      }

      // 只更新 dataset 部分
      this.myChart.setOption({
        dataset: datasets
      })
    } catch (error) {
      console.error('Zoom data fetch error:', error)
      ElMessage({
        message: '获取缩放数据失败: ' + error.message,
        type: 'error',
        duration: 5000,
        showClose: true
      })
    }
  }

  resetZoom() {
    this.myChart.setOption(this.originalOption)
  }

  bindEvents() {
    this.zr.on('mousedown', this.handleMouseDown.bind(this))
    this.zr.on('mousemove', this.handleMouseMove.bind(this))
    this.zr.on('mouseup', this.handleMouseUp.bind(this))
  }

  destroy() {
    if (this.tooltip) {
      document.body.removeChild(this.tooltip)
    }
  }
} 